package me.sdevil507.biz.common.log.service.impl;

import com.google.common.collect.Lists;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import me.sdevil507.biz.common.log.dto.LogDTO;
import me.sdevil507.biz.common.log.mapper.LogMapper;
import me.sdevil507.biz.common.log.po.LogPO;
import me.sdevil507.biz.common.log.po.QLogPO;
import me.sdevil507.biz.common.log.repository.LogRepository;
import me.sdevil507.biz.common.log.service.LogService;
import me.sdevil507.biz.fruit.po.QFruitOrgRelPo;
import me.sdevil507.biz.fruit.po.QFruitPO;
import me.sdevil507.services.dto.HotLogResultDTO;
import me.sdevil507.services.dto.ResultDTO;
import me.sdevil507.supports.jpa.PageParamsDTO;
import me.sdevil507.supports.jpa.SortParamsDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: tips_back_end
 * @description:
 **/
@Service
@Slf4j
public class LogServiceImpl implements LogService {
    @Resource
    private LogRepository logRepository;

    @Autowired
    private LogMapper logMapper;

    @Autowired
    JPAQueryFactory jpaQueryFactory;

    @Override
    public Page<LogPO> readAllByPage(LogDTO searchDTO, PageParamsDTO pageParamsDto, SortParamsDTO sortParamsDto) {

        QLogPO qLogPO = QLogPO.logPO;

        // 开启谓语查询条件
        Predicate predicate = this.getPredicate(searchDTO);

        Sort sort;
        if (null == sortParamsDto) {
            sort = Sort.by(Sort.Direction.DESC, "createTime");
        } else {
            // 排序
            sort = sortParamsDto.getSort();
            if (null == sort) {
                sort = Sort.by(Sort.Direction.DESC, "createTime");
            }
        }

        // 执行返回
        Pageable pageable = pageParamsDto.getPageableWithSort(sort);

        return logRepository.findAll(predicate, pageable);
    }

    public Predicate getPredicate(LogDTO searchDTO){
        QLogPO qLogPO = QLogPO.logPO;
        // 开启谓语查询条件
        Predicate predicate = qLogPO.id.isNotNull();

        String source = searchDTO.getLogSource();
        if (!StringUtils.isEmpty(source)) {
            predicate = ExpressionUtils.and(predicate, qLogPO.logSource.eq(source));
        }

        String logType = searchDTO.getLogType();
        if (!StringUtils.isEmpty(logType)) {
            predicate = ExpressionUtils.and(predicate, qLogPO.logType.eq(logType));
        }

        String logOperate = searchDTO.getLogOperate();
        if (!StringUtils.isEmpty(logOperate)) {
            predicate = ExpressionUtils.and(predicate, qLogPO.logOperate.eq(logOperate));
        }

        Long userId = searchDTO.getUserId();
        if (null != userId && userId.longValue() > 0) {
            predicate = ExpressionUtils.and(predicate, qLogPO.userId.eq(userId));
        }
        return predicate;
    }

    @Override
    public void create(LogDTO logDTO) {
        logRepository.save(logMapper.dto2po(logDTO));
    }

    @Override
    public void update(LogDTO logDTO) {
        logRepository.save(logMapper.dto2po(logDTO));
    }

    @Override
    public List<LogPO> readAll(LogDTO searchDTO, SortParamsDTO sortParamsDto) {
        QLogPO qLogPO = QLogPO.logPO;
        // 开启谓语查询条件
        Predicate predicate = this.getPredicate(searchDTO);

        Sort sort;
        if (null == sortParamsDto) {
            sort = Sort.by(Sort.Direction.DESC, "createTime");
        } else {
            // 排序
            sort = sortParamsDto.getSort();
            if (null == sort) {
                sort = Sort.by(Sort.Direction.DESC, "createTime");
            }
        }

        // 执行Iterable转换List
        List<LogPO> list = Lists.newArrayList(logRepository.findAll(predicate, sort).iterator());
        return list;
    }

    @Override
    public void delete(Long id) {
        LogPO logPO = logRepository.findById(id).get();
        //逻辑删除，将删除状态改为true
        logPO.setIsDel(true);
        logRepository.save(logPO);
    }

    @Override
    public List<HotLogResultDTO> getLogHotRank(LogDTO dto) {

        QLogPO qLogPO = QLogPO.logPO;
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;

        // 开启谓语查询条件
        Predicate predicate = this.getPredicate(dto);

        List<HotLogResultDTO> logList = jpaQueryFactory.select(qLogPO.dataName, qLogPO.dataId, qLogPO.dataId.count())
                .from(qLogPO)
                .leftJoin(qFruitOrgRelPo).on(qFruitOrgRelPo.fruitId.eq(qLogPO.dataId))
                .leftJoin(qFruitPO).on(qFruitPO.id.eq(qFruitOrgRelPo.fruitId))
                .where(qFruitPO.isDel.isFalse().and(qFruitOrgRelPo.orgId.in(dto.getOrgIdList())))
                .where(predicate)
                .groupBy(qLogPO.dataId)
                .orderBy(qLogPO.dataId.count().desc())
                .limit(10)
                .fetch()
                .stream().map(tuple -> {
                    HotLogResultDTO hotLogResultDTO = new HotLogResultDTO();
                    hotLogResultDTO.setId(tuple.get(qLogPO.dataId));
                    hotLogResultDTO.setName(tuple.get(qLogPO.dataName));
                    return hotLogResultDTO;
                }).collect(Collectors.toList());
        return logList;
    }
}
